package com.zlx.mall.basic.currency;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.text.DecimalFormat;

/**
 * 1. BigDecimal格式化输出
 * 2. 主币辅币转换
 * 3. 最小货币单位取整
 *
 * @author qingke
 **/
@Component
public class AmountUtil implements DisposableBean {

    private static final ThreadLocal<DecimalFormat> DEFAULT_FORMAT = createThreadLocalNumberFormat("0.####");
    private static final ThreadLocal<DecimalFormat> COMPLETE_FORMAT = createThreadLocalNumberFormat("#,##0.00");
    private static final ThreadLocal<DecimalFormat> PRETTY_FORMAT = createThreadLocalNumberFormat("#,##0.##");
    private static final ThreadLocal<DecimalFormat> PER_FORMAT = createThreadLocalNumberFormat("0.###%");

    private static ThreadLocal<DecimalFormat> createThreadLocalNumberFormat(final String pattern) {
        return ThreadLocal.withInitial(() -> {
            DecimalFormat decimalFormat = (DecimalFormat) DecimalFormat.getInstance();
            decimalFormat.applyPattern(pattern);
            return decimalFormat;
        });
    }

    @Override
    public void destroy() throws Exception {
        DEFAULT_FORMAT.remove();
        COMPLETE_FORMAT.remove();
        PRETTY_FORMAT.remove();
        PER_FORMAT.remove();
    }


    /**
     * 默认格式化
     * 有小数则保留两位小数的金额格式化
     * 格式: 0.##
     * 例:
     * 0 -> 0
     * 1 -> 1
     * 0.1 -> 0.1
     * 1.104 -> 1.1
     * 1.105 -> 1.11
     * 1000 -> 1000
     */
    public static String defaultFormat(BigDecimal number) {
        return DEFAULT_FORMAT.get().format(number);
    }

    /**
     * 带分组分隔符, 一直保留两位小数的金额格式化
     * 格式: #,##0.00
     * 例:
     * 0 -> 0.00
     * 1 -> 1.00
     * 0.1 -> 0.10
     * 1.104 -> 1.10
     * 1.105 -> 1.11
     * 1000 -> 1,000.00
     */
    public static String completeFormat(BigDecimal number) {
        return COMPLETE_FORMAT.get().format(number);
    }

    /**
     * 带分组分隔符, 有小数则保留两位小数的金额格式化
     * 格式: #,##0.##
     * 例:
     * 0 -> 0
     * 1 -> 1
     * 0.1 -> 0.1
     * 1.104 -> 1.1
     * 1.105 -> 1.11
     * 1000 -> 1,000
     */
    public static String prettyFormat(BigDecimal number) {
        return PRETTY_FORMAT.get().format(number);
    }

    /**
     * 百分比格式化
     * 格式: 0.##%
     * 例:
     * 0 -> 0%
     * 1 -> 100%
     * 0.1 -> 10%
     * 1.104 -> 110.4%
     * 1.105 -> 110.5%
     * 1000 -> 100000%
     * 0.001 -> 0.1%
     * 0.0001 -> 0.01%
     * 0.00001 -> 0%
     * 0.00005 -> 0.01%
     */
    public static String perFormat(BigDecimal number) {
        return PER_FORMAT.get().format(number);
    }


    /**
     * 万分比(基点)
     * 100‱ = 1%
     * 10000‱ = 100% = 1
     * <a href="https://zh.wikipedia.org/wiki/%E8%90%AC%E5%88%86%E7%8E%87">...</a>
     *
     * @param bp Basis Point
     * @return String
     */
    public static BigDecimal basisPointToValue(Integer bp) {
        return new BigDecimal(bp).movePointLeft(4);
    }

    public static BigDecimal basisPointToPer(Integer bp) {
        return new BigDecimal(bp).movePointLeft(2);
    }

    public static BigDecimal basisPointToPerMill(Integer bp) {
        return new BigDecimal(bp).movePointLeft(1);
    }

}
